﻿using System;
using System.Collections.Generic;
using System.Linq;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Audio;
using Microsoft.Xna.Framework.Content;
using Microsoft.Xna.Framework.GamerServices;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input;
using Microsoft.Xna.Framework.Media;
using Microsoft.Xna.Framework.Net;
using Microsoft.Xna.Framework.Storage;

using ProjectPigs.Assets;
using ProjectPigs.Core;
using ProjectPigs.Cameras;

namespace ProjectPigs.Scenes
{
    public class GameScene : Scene
    {
        Texture2D[] bgLayers;

        Strip3D midLayerStrip;
        Strip3D frontLayerStrip;

        BaseCamera[] cameras;
        PPLight[] lights;
        List<String> missingAssets = new List<String>();
        bool maLock = false;

   

        private int meshCount, modelCount;

        public int MeshCount { get { return meshCount; } }
        public int ModelCount { get { return AssetManager.Models.Count; } }

        public static BaseCamera ActiveCamera;

        public GameScene(String name, Map map)
            :base(name)
        {
            bgLayers = new Texture2D[3];

            midLayerStrip = new MidLayerStrip();
            frontLayerStrip = new FrontLayerStrip();

            addMapToMidLayer(map);

        }

        public void addMapToMidLayer(Map map)
        {
            if (midLayerStrip.IsEmpty)
            {
                extractMap(midLayerStrip, map);


            }
            else
            {
                //Debug.pushEntry("WARNING: Map cannot be added to midlayer more than once", 3);
            }
        }

        public void addMapToFrontLayer(Map map)
        {
            extractMap(frontLayerStrip, map);
        }

        public void addGameObject(GameObject gameObject)
        {
            this.gObjects.Add(gameObject);
        }

        protected override void start()
        {
        }

        public override void load(Microsoft.Xna.Framework.Content.ContentManager content)
        {
        }

        public override void draw(Microsoft.Xna.Framework.Graphics.SpriteBatch sb)
        {
            foreach (GameObject obj in gObjects)
            {
                if (obj is RenderableGameObject)
                {
                   if(obj._ID != "dummy")

                    (obj as RenderableGameObject).draw(sb);
                }
            }

            if (!maLock)
            {
                maLock = true;

                foreach( String ma in missingAssets)
                {
                    Debug.pushEntry("WARNING: Asset missing from XNA content: " + ma, 2);
                }
            }

            midLayerStrip.draw();
        }

        public override void update(Microsoft.Xna.Framework.GameTime time)
        {
            if(ActiveCamera != null)
            ActiveCamera.update(time);

            foreach (GameObject obj in gObjects)
            {
                if (obj is DynamicGameObject)
                {
                    (obj as DynamicGameObject).update(time);

                }
            }

            //NOT USED
            /*foreach (PPLight light in lights)
            {
                light.update(time);
            }*/




        }

        private void extractMap(Strip3D strip, Map map)
        {

            meshCount = 0;
            modelCount = 0;
            
            //PRIMARY TIER
            foreach(GeneralAsset asset in map.GeneralAssets)
            {

                if (asset.Type == "Model")
                {

                    PPModel model = AssetManager.findModel(asset.Name);
                    if (model != null)
                    {
                        model.Ref_XNAModel = asset.Name;
                        model.Ref_PPMesh = asset.Group;                        
                       
                        //Convert world coords from Unity to XNA
                        asset.Transform.setPosition_X(asset.Transform.Position.X * -100f);
                        asset.Transform.setPosition_Y(asset.Transform.Position.Y * 100f);
                        asset.Transform.setPosition_Z(asset.Transform.Position.Z * 100f);

                        gObjects.Add(new StaticGameObject(asset.Name, model, asset.Transform));

                    }
                    else
                    {
                        missingAssets.Add(asset.Name);
                    }
                }
            }
            //SECONDARY TIER
            foreach (GeneralAsset asset in map.GeneralAssets)
            {
 
                if (asset.Type.ToLower() == "light")
                {

                }
                else if (asset.Type.ToLower() == "camera")
                {

                }

                else if (asset.Type == "Mesh")
                {
 
                    PPModel m = getModelByGroup(asset.Group);

                    if (m != null)
                    {
                        PPMesh mesh = AssetManager.findMesh(asset.Name, m.Ref_XNAModel);

                        if (mesh != null)
                        {

                            meshCount++;
                        }
                    }
                }
                else if (asset.Type.ToLower() == "collider")
                {

                }
            }

            if (GameScene.ActiveCamera == null)
            {
                //as no camera was found in the map file we'll assign a default camera
                ActiveCamera = new ChaseCamera((gObjects[2] as RenderableGameObject));
            }
        }

        private PPModel getModelByGroup(String groupName)
        {
            foreach (PPModel model in AssetManager.Models)
            {
                if (model.Ref_PPMesh == groupName)
                    return model;
            }

            return null;
        }
    }

    
}
